﻿#include "datadesignerdialog.h"
#include "ui_datadesignerdialog.h"
#include <QDir>
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QCoreApplication>
#include <QMessageBox>

DataDesignerDialog::DataDesignerDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DataDesignerDialog)
{
    ui->setupUi(this);
//    ui->lineEdit->setVisible(false);
    this->setWindowTitle(tr("DataDesignerDialog"));
    this->setObjectName("WidgetDataDesignerDialogObject");

    initDataItems();
}

DataDesignerDialog::~DataDesignerDialog()
{
    delete ui;
}

void DataDesignerDialog::initDataItems()
{
    QDir dir(QCoreApplication::applicationDirPath());
    dir.cdUp();
    dir.cd("config");

    QFile file(dir.absoluteFilePath("dataconfig.xml"));
    if(!file.open(QIODevice::ReadOnly))return;
    QDomDocument doc;
    doc.setContent(&file);
    file.close();

    QDomElement root = doc.firstChildElement("hroot");
    loadXmlNode(nullptr,root);
}

void DataDesignerDialog::saveDataConfig()
{
    QDomDocument doc;
    QDomElement root = doc.createElement("hroot");
    for(int i=0; i<ui->widget->topLevelItemCount(); ++i)
    {
        saveItemToNode(ui->widget->topLevelItem(i),doc,root);
    }
    doc.appendChild(root);

    QDir dir(QCoreApplication::applicationDirPath());
    dir.cdUp();
    dir.cd("config");

    QFile file(dir.absoluteFilePath("dataconfig.xml"));
    if(!file.open(QIODevice::WriteOnly))return;
    QString sxml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
    sxml.append(doc.toString());
    file.write(sxml.toUtf8().data());
    file.close();
}

void DataDesignerDialog::generateCode()
{
    if(ui->lineEdit->text().isEmpty())
    {
        QMessageBox::warning(this,tr("warning"),tr("please input project name"));
        return;
    }

    // 生成数据对象的代码
    QString sDir = QFileDialog::getExistingDirectory(this,tr("Please Select Code Path"));
    if(sDir.isEmpty())return;
    QDir dir(sDir);
    if(!dir.exists(ui->lineEdit->text()))
        dir.mkdir(ui->lineEdit->text());
    dir.cd(ui->lineEdit->text());

    if(ui->checkBox->isChecked())
    {
        generateProFile(dir.absolutePath(),ui->lineEdit->text());
    }

    for(int i=0; i<ui->widget->topLevelItemCount(); ++i)
    {
        generateByTreeItem(ui->widget->topLevelItem(i),dir.absolutePath());
    }

    // 更新配置文件
    saveDataConfig();
}

void DataDesignerDialog::generateByTreeItem(QTreeWidgetItem *pTreeItem,const QString& path)
{
    if(nullptr == pTreeItem)return;

    QDir dir(path);
    if(!dir.exists())return;

    if(pTreeItem->checkState(0) == Qt::Checked)
    {
        QString dataType = pTreeItem->data(0,Qt::DisplayRole).toString();
        QString sID = pTreeItem->data(0,Qt::WhatsThisRole).toString();
        generateDataControlHeader(path,dataType);
        generateDataControlCpp(path,dataType);
        generateDataObjectHeader(path,dataType);
        generateDataObjectCpp(path,dataType);
    }
    // 如果当前节点有子节点，自动执行子节点
    for(int i=0; i<pTreeItem->childCount(); ++i){
        generateByTreeItem(pTreeItem->child(i),path);
    }
}

void DataDesignerDialog::generateDataControlHeader(const QString& path,const QString &className)
{
    QFile tempFile(":/ModelFile/BundleDesigner/datacontrolheader.temp");
    if(!tempFile.open(QIODevice::ReadOnly))
    {
        return;
    }

    QTextStream in(&tempFile);

    QDir fileDir(path);
    QFile file(fileDir.absolutePath()+"/"+className.toLower()+"datacontrol.h");
    if(!file.open(QIODevice::WriteOnly))
    {
        return;
    }
    QTextStream out(&file);

    while(!in.atEnd())
    {
        QString sLine = in.readLine();
        sLine.replace("[name]",className);
        sLine.replace("[name_upper]",className.toUpper());
        sLine.replace("[name_lower]",className.toLower());
        sLine.replace("[proname_upper]",ui->lineEdit->text().toUpper());
        out<<sLine<<"\r\n";
    }
    file.close();
    tempFile.close();
}

void DataDesignerDialog::generateDataControlCpp(const QString& path,const QString &className)
{
    QFile tempFile(":/ModelFile/BundleDesigner/datacontrolcpp.temp");
    if(!tempFile.open(QIODevice::ReadOnly))
    {
        return;
    }

    QTextStream in(&tempFile);

    QDir fileDir(path);
    QFile file(fileDir.absolutePath()+"/"+className.toLower()+"datacontrol.cpp");
    if(!file.open(QIODevice::WriteOnly))
    {
        return;
    }
    QTextStream out(&file);

    while(!in.atEnd())
    {
        QString sLine = in.readLine();
        sLine.replace("[name]",className);
        sLine.replace("[name_upper]",className.toUpper());
        sLine.replace("[name_lower]",className.toLower());
        out<<sLine<<"\r\n";
    }
    file.close();
    tempFile.close();
}

void DataDesignerDialog::generateDataObjectHeader(const QString& path,const QString &className)
{
    QFile tempFile(":/ModelFile/BundleDesigner/dataobjectheader.temp");
    if(!tempFile.open(QIODevice::ReadOnly))
    {
        return;
    }

    QTextStream in(&tempFile);

    QDir fileDir(path);
    QFile file(fileDir.absolutePath()+"/"+className.toLower()+"dataobject.h");
    if(!file.open(QIODevice::WriteOnly))
    {
        return;
    }
    QTextStream out(&file);

    while(!in.atEnd())
    {
        QString sLine = in.readLine();
        sLine.replace("[name]",className);
        sLine.replace("[name_upper]",className.toUpper());
        sLine.replace("[name_lower]",className.toLower());
        sLine.replace("[proname_upper]",ui->lineEdit->text().toUpper());
        out<<sLine<<"\r\n";
    }
    file.close();
    tempFile.close();
}

void DataDesignerDialog::generateDataObjectCpp(const QString& path,const QString &className)
{
    QFile tempFile(":/ModelFile/BundleDesigner/dataobjectcpp.temp");
    if(!tempFile.open(QIODevice::ReadOnly))
    {
        return;
    }

    QTextStream in(&tempFile);

    QDir fileDir(path);
    QFile file(fileDir.absolutePath()+"/"+className.toLower()+"dataobject.cpp");
    if(!file.open(QIODevice::WriteOnly))
    {
        return;
    }
    QTextStream out(&file);

    while(!in.atEnd())
    {
        QString sLine = in.readLine();
        sLine.replace("[name]",className);
        sLine.replace("[name_upper]",className.toUpper());
        sLine.replace("[name_lower]",className.toLower());
        out<<sLine<<"\r\n";

    }
    file.close();
    tempFile.close();
}

void DataDesignerDialog::saveItemToNode(QTreeWidgetItem *pTreeItem, QDomDocument doc, QDomElement parnode)
{
    if(pTreeItem == nullptr || parnode.isNull())return;

    QDomElement datanode = doc.createElement("data");
    datanode.setAttribute("type",pTreeItem->data(0,Qt::DisplayRole).toString());
    datanode.setAttribute("id",pTreeItem->data(0,Qt::WhatsThisRole).toString());
    datanode.setAttribute("mincount",pTreeItem->data(1,Qt::DisplayRole).toString());
    datanode.setAttribute("maxcount",pTreeItem->data(2,Qt::DisplayRole).toString());
    datanode.setAttribute("info",pTreeItem->data(3,Qt::DisplayRole).toString());
    parnode.appendChild(datanode);

    for(int i=0; i<pTreeItem->childCount(); ++i)
    {
        saveItemToNode(pTreeItem->child(i),doc,datanode);
    }
}

void DataDesignerDialog::loadXmlNode(QTreeWidgetItem *pParentItem, QDomElement parNode)
{
    QDomElement datanode = parNode.firstChildElement("data");
    while (!datanode.isNull()) {
        QTreeWidgetItem* pTreeItem = new QTreeWidgetItem();
        pTreeItem->setData(0,Qt::DisplayRole,datanode.attribute("type"));
        pTreeItem->setData(0,Qt::WhatsThisRole,datanode.attribute("id"));
        pTreeItem->setData(1,Qt::DisplayRole,datanode.attribute("mincount"));
        pTreeItem->setData(2,Qt::DisplayRole,datanode.attribute("maxcount"));
        pTreeItem->setData(3,Qt::DisplayRole,datanode.attribute("info"));
        int operate = 0xff;
        if(datanode.hasAttribute("operate")){
            operate = datanode.attribute("operate").toInt();
        }

        pTreeItem->setData(4,Qt::WhatsThisRole,operate);

        pTreeItem->setCheckState(0,Qt::Unchecked);

        if(datanode.childNodes().count() > 0)
        {
            loadXmlNode(pTreeItem,datanode);
        }

        if(pParentItem == nullptr)
        {
            ui->widget->addTopLevelItem(pTreeItem);
        }
        else {
            pParentItem->addChild(pTreeItem);
            if(!pParentItem->isExpanded()){
                pParentItem->setExpanded(true);
            }
        }
        if(!pTreeItem->isExpanded()){
            pTreeItem->setExpanded(true);
        }
        datanode = datanode.nextSiblingElement("data");
    }
}

QVector<QTreeWidgetItem *> DataDesignerDialog::getAllCheckedItem(QTreeWidgetItem* parItem)
{
    QVector<QTreeWidgetItem *> vctItems;
    if(nullptr == parItem)return vctItems;

    for(int i=0; i<parItem->childCount(); ++i)
    {
        if(parItem->child(i)->checkState(0) == Qt::Checked)
        {
            vctItems.append(parItem->child(i));
        }

        if(parItem->child(i)->childCount() > 0)
        {
            vctItems.append(getAllCheckedItem(parItem->child(i)));
        }
    }

    return vctItems;
}

void DataDesignerDialog::generateProFile(const QString &path, const QString &name)
{
    QFile tempFile(":/ModelFile/BundleDesigner/datapro.temp");
    if(!tempFile.open(QIODevice::ReadOnly))
    {
        return;
    }

    QTextStream in(&tempFile);

    QDir fileDir(path);
    QFile file(fileDir.absolutePath()+"/"+name.toLower()+".pro");
    if(!file.open(QIODevice::WriteOnly))
    {
        return;
    }
    QTextStream out(&file);

    // 导出的数据类列表
    QVector<QTreeWidgetItem *> vctCheckedItems;
    for(int i=0; i<ui->widget->topLevelItemCount(); ++i)
    {
        if(ui->widget->topLevelItem(i)->checkState(0) == Qt::Checked)
        {
            vctCheckedItems.append(ui->widget->topLevelItem(i));
        }
        vctCheckedItems.append(getAllCheckedItem(ui->widget->topLevelItem(i)));
    }

    while(!in.atEnd())
    {
        QString sLine = in.readLine();

        if(sLine.contains("[datacontrolcpp]"))
        {
            foreach (QTreeWidgetItem* p, vctCheckedItems) {
                QString sctrl = QString("        %1datacontrol.cpp \\").arg(p->data(0,Qt::DisplayRole).toString().toLower());
                out<<sctrl<<"\r\n";
                QString sobj = QString("        %1dataobject.cpp \\").arg(p->data(0,Qt::DisplayRole).toString().toLower());
                out<<sobj<<"\r\n";
            }
            continue;
        }
        else if(sLine.contains("[datacontrolheader]"))
        {
            foreach (QTreeWidgetItem* p, vctCheckedItems) {
                QString sctrl = QString("        %1datacontrol.h \\").arg(p->data(0,Qt::DisplayRole).toString().toLower());
                out<<sctrl<<"\r\n";
                QString sobj = QString("        %1dataobject.h \\").arg(p->data(0,Qt::DisplayRole).toString().toLower());
                out<<sobj<<"\r\n";
            }
            continue;
        }
        else {
            sLine.replace("[name]",name);
            sLine.replace("[name_upper]",name.toUpper());
            sLine.replace("[name_lower]",name.toLower());
            out<<sLine<<"\r\n";
        }


    }
    file.close();
    tempFile.close();
}
